#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project : POS_api_test_project 
@File    : posRequestControl.py
@IDE     : PyCharm 
@Author  : Mario
@Date    : 2022/5/28 12:39 
@Describe: POS接口请求
"""
import json
import requests
from typing import Any
from Enums.yaml_data_enum import YAMLData
from Enums.request_type_enum import RequestType
from Utils.mysqlUtils.mysqlControl import MysqlDB
from Utils.logUtils.logDecorator import log_decorator
from Utils.otherUtils.get_conf_data import sql_switch
from Utils.requestsUtils.get_headers import get_headers
from Utils.logUtils.runTimeDecorator import execution_duration
from Utils.otherUtils.allureData.allure_tools import allure_step, allure_step_no
from Utils.otherUtils.jsonpath_date_replace import get_json_result, get_json_valus


class PosRequestControl:

    @classmethod
    def _check_params(cls, response, yaml_data, headers, cookie, res_time, status_code, teardown, teardown_sql, TraceId) -> Any:
        """ 抽离出通用模块，判断 http_request 方法中的一些数据校验 """
        # 判断数据库开关，开启状态，则返回对应的数据
        if sql_switch() and yaml_data['sql'] is not None:
            sql_data = MysqlDB().assert_execution(sql=yaml_data['sql'], resp=response)
            return {"response_data": response, "sql_data": sql_data, "yaml_data": yaml_data,
                    "headers": headers, "cookie": cookie, "res_time": res_time, "status_code": status_code,
                    "teardown": teardown, "teardown_sql": teardown_sql, "TraceId": TraceId}
        else:
            # 数据库关闭走的逻辑
            res = response
            return {"response_data": res, "sql_data": {"sql": None}, "yaml_data": yaml_data,
                    "headers": headers, "cookie": cookie, "res_time": res_time, "status_code": status_code,
                    "teardown": teardown, "teardown_sql": teardown_sql, "TraceId": TraceId}

    @log_decorator(True)
    @execution_duration(5000)
    def http_requests(self, yaml_data, dependent_switch=True):
        # 用例是否执行
        _is_run = yaml_data[YAMLData.IS_RUN.value]
        # 请求方式
        _method = yaml_data[YAMLData.METHOD.value]
        # 用例描述
        _detail = yaml_data[YAMLData.DETAIL.value]
        # 请求头
        _headers = yaml_data[YAMLData.HEADER.value]
        # 请求类型
        _requestType = yaml_data[YAMLData.REQUEST_TYPE.value]
        _data = json.dumps(yaml_data[YAMLData.DATA.value])
        # sql内容
        _sql = yaml_data[YAMLData.SQL.value]
        # 断言内容
        _assert = yaml_data[YAMLData.ASSERT.value]
        # 依赖用例参数
        _dependent_data = yaml_data[YAMLData.DEPENDENCE_CASE_DATA.value]
        _teardown = yaml_data[YAMLData.TEARDOWN.value]
        _teardown_sql = yaml_data[YAMLData.TEARDOWN_SQL.value]
        response = None
        # 判断用例是否执行
        if _is_run is True or _is_run is None:
            # 处理多业务逻辑
            if dependent_switch is True:
                from Utils.requestsUtils.dependentCase import DependentCase
                DependentCase().get_dependent_data(yaml_data)
            if _requestType == RequestType.JSON.value:
                headers = get_headers()
                _headers = headers
                response = requests.request(method=_method, url=yaml_data[YAMLData.URL.value], data='{}'.format(_data),
                                            headers=headers)
            response_time = response.elapsed.total_seconds()  # 接口响应时间
            response_code = get_json_result(response, '$.code')  # 接口响应状态码
            TraceId = get_json_valus(response.headers, key='X-B3-TraceId')  # 日志ID
            allure_step_no(f"请求URL: {yaml_data[YAMLData.URL.value]}")
            allure_step_no(f"请求方式: {_method}")
            allure_step("请求头: ", _headers)
            allure_step("请求数据: ", _data)
            allure_step("依赖数据: ", _dependent_data)
            allure_step("预期数据: ", _assert)
            allure_step_no(f"响应耗时: {response_time}秒")
            allure_step_no(f"TraceId: {TraceId}")
            response_json = response.json()
            allure_step("响应结果: ", response_json)
            cookie = None
            return self._check_params(response_json, yaml_data, _headers, cookie, response_time,
                                      response_code, _teardown, _teardown_sql, TraceId)
        else:
            # 用例跳过执行的话，响应数据和sql数据为空
            return {"response_data": False, "sql_data": False, "yaml_data": yaml_data, "res_time": 0.00}


if __name__ == '__main__':
    test_dict = {'method': 'POST', 'is_run': None, 'url': 'http://api-test.gtmsh.com/catering-pos-api/v1/table/list', 'detail': '所有台位列表接口', 'headers': None, 'requestType': 'JSON',
                 'data': {'operate': ''}, 'dependence_case': False, 'dependence_case_data': {'dependence_case_data': None}, 'sql': None,
                 'assert': {'code': {'jsonpath': '$.code', 'type': '==', 'value': 200, 'AssertType': None}}, 'setup_sql': None, 'teardown': None, 'teardown_sql': None}
    test = PosRequestControl()
    test.http_requests(test_dict)
